package org.hackystat.sdsa.analyzer.model.activity;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.logging.Logger;

import javax.xml.datatype.XMLGregorianCalendar;

import jess.Fact;

import org.hackystat.sdsa.service.resource.devstream.jaxb.ActivityTO;
import org.hackystat.sensorbase.resource.sensordata.jaxb.Properties;
import org.hackystat.sensorbase.resource.sensordata.jaxb.Property;
import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData;
import org.hackystat.utilities.tstamp.Tstamp;
import org.junit.Test;

/**
 * Tests unit testing activity.
 * 
 * @author Hongbing Kou
 */
public class TestUnitTestActivity extends ActivityTestBase {
  /** Sensor data */
  private SensorData sensorData;
  private Logger logger; 

  /**
   * Prepares the testing environment.
   * 
   * @throws Exception If any error happens.
   */
  @Override public void setUp() throws Exception {
    super.setUp();  
    this.sensorData = new SensorData();
    XMLGregorianCalendar tstamp = Tstamp.makeTimestamp("2005-12-01T08:30:00.000-10:00");
    sensorData.setTimestamp(tstamp);
    sensorData.setResource("file:/C:/cvs/work/com/foo/TestBar.java");
    sensorData.setSensorDataType("DevEvent");
    this.logger = Logger.getLogger(TestUnitTestActivity.class.getName());

    XMLGregorianCalendar runtimeCal = Tstamp.makeTimestamp("2007-11-17T10:25:00.000-08:00");
    sensorData.setRuntime(runtimeCal);

    // Add property
    Properties props = new Properties();
    sensorData.setProperties(props);

    Property type = new Property();
    type.setKey("Type");
    type.setValue("Test");
    props.getProperty().add(type);
    
    Property failureString = new Property();
    failureString.setKey(UnitTestActivity.FAILURE_STRING);
    failureString.setValue("");
    props.getProperty().add(failureString);

    Property elapsedTime = new Property();
    elapsedTime.setKey(UnitTestActivity.ELAPSED_TIME);
    elapsedTime.setValue("12");
    props.getProperty().add(elapsedTime);

    Property testName = new Property();
    testName.setKey(UnitTestActivity.TEST_NAME);
    testName.setValue("testSingle()");
    props.getProperty().add(testName);

    Property testCase = new Property();
    testCase.setKey(UnitTestActivity.TEST_CASE);
    testCase.setValue("TestBar");
    props.getProperty().add(testCase);

    Property testCount = new Property();
    testCount.setKey(UnitTestActivity.TEST_COUNT);
    testCount.setValue("1");
    props.getProperty().add(testCount);

    Property testIndice = new Property();
    testIndice.setKey(UnitTestActivity.TEST_INDICE);
    testIndice.setValue("1");
    props.getProperty().add(testIndice);

  }
  
  /**
   * Tests unit test action.
   * 
   * @throws Exception If error while testing.
   */
  @Test public void testUnitTestAction() throws Exception {
    UnitTestActivity action = new UnitTestActivity (this.sensorData, this.logger);
    assertEquals("Test unit test string", 
        "2005-12-01T08:30:00.000-10:00 TestBar.java UNIT TEST PASSED", 
                 action.toString());
    
    String timeString = this.sensorData.getTimestamp().toString();
    assertEquals("Test unit test string", 
        timeString + " TestBar.java UNIT TEST PASSED", 
         action.toString());
    
    action.setFailureMessage("Name can not be compound");
    assertNotNull("Test message", action.getFailureMessage());
    
    assertEquals("Test unit test string", 
        "2005-12-01T08:30:00.000-10:00 TestBar.java UNIT TEST FAILED", 
        action.toString());
  }
  
  /**
   * Tests conversion from action object to JESS fact.
   * 
   * @throws Exception If error while converting to Jess fact.
   */
  @Override public void testJessFactConversion() throws Exception {
    UnitTestActivity action = new UnitTestActivity(this.sensorData, this.logger);
    action.setFailureMessage("0 returned while expecting -2.");
    
    Fact f = action.assertActivity(1, engine);    
    assertTrue("Test action is asserted to working memory", f.getFactId() >= 0);    
  }
  
  /**
   * Tests the conversion to Transfer Object.
   * 
   * @throws Exception If error occurs during testing.
   */
  @Test public void testTOConversion() throws Exception {
    UnitTestActivity activity = new UnitTestActivity(this.sensorData, this.logger);
    activity.setFailureMessage("0 returned while expecting -2.");
    ActivityTO activityTO = activity.convert();
    assertEquals("Test ActivityTO file", "TestBar.java", activityTO.getFile());

    XMLGregorianCalendar tstamp = Tstamp.makeTimestamp("2005-12-01T08:30:00.000-10:00");
    assertEquals("Test ActivityTO timestamp", tstamp, activityTO.getTime());
  }
  
}
